home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / fs / minix / symlink.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  2.1 KB  |  107 lines

  1. /*
  2.  *  linux/fs/minix/symlink.c
  3.  *
  4.  *  Copyright (C) 1991, 1992  Linus Torvalds
  5.  *
  6.  *  minix symlink handling code
  7.  *
  8.  * This file is subject to the terms and conditions of the GNU General Public
  9.  * License.  See the file README.legal in the main directory of this archive
  10.  * for more details.
  11.  */
  12.  
  13. #include <asm/segment.h>
  14.  
  15. #include <linux/errno.h>
  16. #include <linux/sched.h>
  17. #include <linux/fs.h>
  18. #include <linux/minix_fs.h>
  19. #include <linux/stat.h>
  20.  
  21. static int minix_readlink(struct inode *, char *, int);
  22. static int minix_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  23.  
  24. /*
  25.  * symlinks can't do much...
  26.  */
  27. struct inode_operations minix_symlink_inode_operations = {
  28.     NULL,            /* no file-operations */
  29.     NULL,            /* create */
  30.     NULL,            /* lookup */
  31.     NULL,            /* link */
  32.     NULL,            /* unlink */
  33.     NULL,            /* symlink */
  34.     NULL,            /* mkdir */
  35.     NULL,            /* rmdir */
  36.     NULL,            /* mknod */
  37.     NULL,            /* rename */
  38.     minix_readlink,        /* readlink */
  39.     minix_follow_link,    /* follow_link */
  40.     NULL,            /* bmap */
  41.     NULL,            /* truncate */
  42.     NULL            /* permission */
  43. };
  44.  
  45. static int minix_follow_link(struct inode * dir, struct inode * inode,
  46.     int flag, int mode, struct inode ** res_inode)
  47. {
  48.     int error;
  49.     struct buffer_head * bh;
  50.  
  51.     *res_inode = NULL;
  52.     if (!dir) {
  53.         dir = current->root;
  54.         dir->i_count++;
  55.     }
  56.     if (!inode) {
  57.         iput(dir);
  58.         return -ENOENT;
  59.     }
  60.     if (!S_ISLNK(inode->i_mode)) {
  61.         iput(dir);
  62.         *res_inode = inode;
  63.         return 0;
  64.     }
  65.     if (current->link_count > 5) {
  66.         iput(inode);
  67.         iput(dir);
  68.         return -ELOOP;
  69.     }
  70.     if (!(bh = minix_bread(inode, 0, 0))) {
  71.         iput(inode);
  72.         iput(dir);
  73.         return -EIO;
  74.     }
  75.     iput(inode);
  76.     current->link_count++;
  77.     error = open_namei(bh->b_data,flag,mode,res_inode,dir);
  78.     current->link_count--;
  79.     brelse(bh);
  80.     return error;
  81. }
  82.  
  83. static int minix_readlink(struct inode * inode, char * buffer, int buflen)
  84. {
  85.     struct buffer_head * bh;
  86.     int i;
  87.     char c;
  88.  
  89.     if (!S_ISLNK(inode->i_mode)) {
  90.         iput(inode);
  91.         return -EINVAL;
  92.     }
  93.     if (buflen > 1023)
  94.         buflen = 1023;
  95.     bh = minix_bread(inode, 0, 0);
  96.     iput(inode);
  97.     if (!bh)
  98.         return 0;
  99.     i = 0;
  100.     while (i<buflen && (c = bh->b_data[i])) {
  101.         i++;
  102.         put_fs_byte(c,buffer++);
  103.     }
  104.     brelse(bh);
  105.     return i;
  106. }
  107.